﻿#region

using System.Collections.Generic;
using System.Text;
using OMS.Ice.T4Generator.Properties;
using OMS.Ice.T4Generator.Syntax;

#endregion


namespace OMS.Ice.T4Generator
{
    internal class CSCodeBuilder : CodeBuilder
    {
        protected override string GetCodeTemplate()
        {
            return Resources.CSCodeTemplate;
        }

        protected override string GetIncludeTemplate()
        {
            return Resources.CSIncludeTemplate;
        }

        protected override StringBuilder CreateImports( IEnumerable<string> imports )
        {
            var result = new StringBuilder();

            foreach( var import in imports )
                result.AppendLine( string.Format( "using {0};", import ) );

            return result;
        }

        protected override StringBuilder CreateFields( IEnumerable<Parameter> parameters )
        {
            var result = new StringBuilder();

            foreach( var parameter in parameters )
                result.AppendLine( string.Format( "\t\tprivate {0} {1};", parameter.Type, parameter.Name ) );

            return result;
        }

        protected override StringBuilder CreateParameters( IEnumerable<Parameter> parameters )
        {
            var result = new StringBuilder();

            var first = true;
            foreach( var parameter in parameters )
            {
                if( !first )
                    result.Append( ", " );
                first = false;

                result.Append( string.Format( "{0} {1}", parameter.Type, parameter.Name ) );
            }

            return result;
        }

        protected override StringBuilder CreateCallParameters(IEnumerable<Parameter> parameters)
        {
            var result = new StringBuilder();

            var first = true;
            foreach (var parameter in parameters)
            {
                if (!first)
                    result.Append(", ");
                first = false;

                result.Append(string.Format("{0}", parameter.Name));
            }

            return result;
        }

        protected override StringBuilder CreateFieldInitializers( IEnumerable<Parameter> parameters )
        {
            var result = new StringBuilder();

            foreach( var parameter in parameters )
                result.AppendLine( string.Format( "\t\t\tthis.{0} = {0};", parameter.Name ) );

            return result;
        }

        protected override StringBuilder CreateTextBlock( StringBuilder result, IEnumerable<string> content )
        {
            foreach( var line in content )
                result.AppendLine( string.Format( "\t\t\tWrite( \"{0}\" );", Escape( line ) ) );

            return result;
        }

        protected override StringBuilder CreateInlineCode( StringBuilder result, string statement )
        {
            result.AppendLine( string.Format( "\t\t\tWrite( {0} );", statement ) );

            return result;
        }

        protected override StringBuilder CreateMethodCall( StringBuilder result, IncludeDirective directive )
        {
            var parameters = GetParameters( IncludedTemplates[directive] );

            result.AppendLine(string.Format("\t\t\t{0}TemplateMethod({1});", directive.Name, CreateCallParameters(parameters)));

            return result;
        }

        protected override string CreateLinePragma(Part part)
        {
            return string.Format("#line {0} \"{1}\"\r\n", part.Line, part.Source);
        }


        private static string Escape( string text )
        {
            return text.Replace( "\\", "\\\\" ).Replace( "\"", "\\\"" );
        }
    }
}